package cz.data.common.database;

import com.alibaba.fastjson.JSONObject;
import cz.data.common.support.db.core.DbColumn;
import cz.data.common.support.db.core.DbTable;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 表数据查询接口
 */
public interface DbDialect {

    RowMapper<DbTable> tableMapper();

    RowMapper<DbColumn> columnMapper();

    /**
     * 获取指定表的所有列
     *
     * @param dbName
     * @param tableName
     * @return
     */
    String columns(String dbName, String schemaName, String tableName);

    /**
     * 获取数据库下的 所有表
     *
     * @param dbName
     * @return
     */
    String tables(String dbName, String schemaName);

    /**
     * 构建 分页 sql
     *
     * @param sql
     * @param offset
     * @param count
     * @return
     */
    String buildPaginationSql(String sql, long offset, long count);

    /**
     * 包装 count sql
     *
     * @param sql
     * @return
     */
    String count(String sql);

    default String tableNames(String dbName, String schema) {
        throw new UnsupportedOperationException("数据源不适配 tableNames");
    }

    default String columnNames(String dbName, String schema, String tableName) {
        throw new UnsupportedOperationException("数据源不适配 columnNames");
    }

    PreparedStatementCreator insertSQL(JSONObject json, String table, String[] insertFields);

    PreparedStatementCreator batchInsertSQL(List<JSONObject> records, String table, String[] insertFields);

    PreparedStatementCreator updateSQL(String table, JSONObject json, String[] updateFields, String[] primaryKeys);

    default PreparedStatementCreator upsertSQL(List<JSONObject> records, String table, List<String> primaryKeys, String[] insertFields, String[] updateFields) {
        throw new UnsupportedOperationException("数据源不适配 upsert");
    }

    static String updateCommandBuilder(String table, String[] primaryKeys, String[] updateFields) {
        StringBuilder statement = new StringBuilder("UPDATE ").append(table).append(" SET ");
        String setStatement = Arrays.stream(updateFields)
                .map(f -> f + " = ?")
                .collect(Collectors.joining(","));
        statement.append(setStatement).append(" WHERE ");
        String whereStatement = Arrays.stream(primaryKeys)
                .map(key -> key + " = ?")
                .collect(Collectors.joining(" AND "));
        statement.append(whereStatement);
        return statement.toString();
    }
}
